#include <iostream>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

void wait(int seconds = 1)
{
  boost::this_thread::sleep(boost::posix_time::seconds(seconds));
}

boost::mutex mutex;

void thread()
{
  try {
    
    //std::cout << " Thread #" << boost::this_thread::get_id() << std::endl;
    for (int i = 0; i < 5; ++i) {
      wait();
      boost::lock_guard<boost::mutex> lock(mutex);
      std::cout << i << " " << boost::this_thread::get_id() << std::endl;
    }
  }
  catch (boost::thread_interrupted&) {
    std::cout << "interrupted" << std::endl;
  }
}

const int N_thread = 1;
int N_hello = 0;

void hello()
{
  for (int i = 0; i < 100000/N_thread; ++i) {
    boost::lock_guard<boost::mutex> lock(mutex);
    std::cout << "hello " << ++N_hello << " ";
  }  
}

const int N = 1000000000;
std::vector<bool> prime_table(N, true);

void fill_prime(int start, int step, int n)
{
  for (int i = start; i < N && i < start + step*n; i += step)
    prime_table[i] = false;
}

int main(int argc, char** argv) 
{
  std::cout << "BOOST thread ... " << std::endl;
  boost::thread* threads[N_thread];

  boost::posix_time::ptime time_start(boost::posix_time::microsec_clock::local_time());

  int sqrtN = (int) sqrt(N);
  for (int i = 2; i <= sqrtN; i++) if (prime_table[i]) {
    int start = i * i;
    int total_n = (N-start) / i;
    int each_n = total_n / N_thread + 1;
    for (int k = 0; k < N_thread; k++) {
      threads[k] = new boost::thread(fill_prime, start, i, each_n);
      start += i * each_n;
    }
    BOOST_FOREACH(boost::thread* t, threads)
      t->join();

    BOOST_FOREACH(boost::thread* t, threads)
      delete t;
    
  }

  boost::posix_time::ptime time_end(boost::posix_time::microsec_clock::local_time());
  boost::posix_time::time_duration duration(time_end - time_start);

  int count = 0;
  for (int i = 2; i < N; i++) 
    if (prime_table[i]) {
      //std::cout << i << " "; 
      count++;
    }
  std::cout << std::endl << "total " << count << " prime numbers" << std::endl;
  std::cerr << "Duration = " << duration << "\n";
}
